<?php

namespace app\home\controller;

// 引入控制器基类
use think\Controller;

// 引入插件类
use think\captcha\Captcha;

// 引入Db类
use think\Db;

class Index extends Controller
{

    // 构造函数 全局加载一个模型
    public function __construct()
    {
        // 继承父类的构造函数 避免覆盖 已覆盖 控制器基类的方法不可用
        parent::__construct();

        // 全局加载一个模型
        $this->UserModel = model('User.User');
        $this->PostModel = model('Post.Post');
        $this->CollectModel = model('Collect');
    }

    // 首页
    public function index()
    {
        // 接受分类id
        $cateid = $this->request->param('cateid', 'all', 'trim');  //帖子分类
        $state = $this->request->param('state', 'all', 'trim');
        $keywords = $this->request->param('keywords', '', 'trim'); //关键词搜索   在tp5内部
        $accept = $this->request->param('accept', '', 'trim');

        $where = [];

        // 判断是否有传递分类id的参数
        if ($cateid != 'all') {
            $where['cateid'] = $cateid;
        }

        // 不等于all就是要查询某一类的条件
        if ($state != "all") {
            $where['state'] = $state;
        }

        // 采纳人 不为空已采纳 为空未采纳
        if (!empty($accept)) {
            // IS NOT NULL是不为空
            $where['accept'] = ['EXP', Db::raw('IS NOT NULL')];
        } else {
            // IS NULL是为空
            $where['accept'] = ['EXP', Db::raw('IS NULL')];
        }

        // 不为空做模糊查询
        if (!empty($keywords)) {
            $where['title'] = ['like', "%$keywords%"];
        }

        // 查询帖子数据
        // $postlist=model('Post.Post')->order('createtime desc,id desc')->paginate(6);
        $postlist = model('Post.Post')->with(['user', 'cate'])->where($where)->order('createtime desc,id desc')->paginate(6);


        //---------------------------------------------------------------

        // 查询本周所有的帖子 tp内置方法
        $week = model('Post.Post')->whereTime('createtime', 'week')->select();

        if ($week) {
            $week = ArraySequence(collection($week)->toArray(), "visit_total");

            // 数组截取
            $week = array_slice($week, 0, 10);
        }




        // ------------------------回帖周榜-------------------------

        // 查询本周
        $date = new \DateTime();

        // 获取本周的第一天  默认为该周的第一天 星期一
        $date->modify('this week');
        $start = strtotime($date->format('Y-m-d'));

        // 获取本周的周日
        $date->modify('this week +6 days');
        $end = strtotime($date->format('Y-m-d'));

        // 查询回帖周榜
        $sql = "SELECT count(*) AS num, user.nickname,user.avatar,user.id FROM pre_comment AS comment LEFT JOIN pre_user AS user ON comment.userid = user.id WHERE comment.createtime between $start and $end GROUP BY comment.userid ORDER BY num DESC LIMIT 12";

        // 查询出来的数据
        $userlist = Db::query($sql);

        //------------------



        //查询系统的签到积分数
        $SignPoint = model('Config')->where(['key' => 'SignPoint'])->value('value');
        $SignPoint = abs(intval($SignPoint)) > 0 ? abs(intval($SignPoint)) : 5;



        // 查询帖子分类表
        $catelist = model('Post.Cate')->limit(6)->select();

        // 赋值给前台模板
        $this->view->assign([
            'catelist' => $catelist,
            'postlist' => $postlist,
            'accept' => $accept,
            'week' => $week,
            'userlist' => $userlist,
            'SignPoint' => $SignPoint,

            // 传递接受到的参数
            'cateid' => $cateid,
            'state' => $state,

        ]);

        return $this->view->fetch();
    }

    // 详细界面
    public function info()
    {
        // 获取传过来的id
        $postid = $this->request->param('postid', 0, 'trim');

        // 查询当前的帖子id等于这个帖子的id显示已收藏
        $Collect= model('Collect')->where(['postid' => $postid])->select();

        // 链表查询
        $post = model('Post.Post')->with(['user', 'cate'])->find($postid);


        //----------------------帖子访问--------------------------------
        // 判断这个帖子存不存在
        if (!$post) {
            $this->error('帖子不存在');
            exit;
        }


        // 判断用户是否登录
        // 获取cookie
        $LoginUser = cookie('LoginUser') ? cookie('LoginUser') : [];

        if (!empty($LoginUser)) {

            // 用户id
            $userid = isset($LoginUser['id']) ? $LoginUser['id'] : 0;

            // 拿到用户id查询数据库看存不存在
            $LoginUser = $this->UserModel->find($userid);

            // 用户存在往下走
            if ($LoginUser) {

                // 先获取帖子的访问人id
                $visit = $post['visit'];

                // 为空给一个空数组 不为空就转化为数组
                $visit = empty($visit) ? [] : explode(',', $visit);

                // 如果当前的用户id在访问数组中就说明已访问过，反之则反
                // in_array($LoginUser['id'],$visit) 查看当前用户的id在不在$visit中
                if (!in_array($LoginUser['id'], $visit)) {
                    // 追加id进入 然后转化为字符串
                    $visit[] = $LoginUser['id'];
                    // 转化为字符串
                    $visitStr = implode(',', $visit);

                    $PostData = [
                        'id' => $post['id'],
                        'visit' => $visitStr,
                    ];

                    // 更新这个帖子
                    model('Post.Post')->isUpdate(true)->save($PostData);
                }
            }
        }

        // 查询本周所有的帖子 tp内置方法
        $week = model('Post.Post')->whereTime('createtime', 'week')->select();

        if ($week) {
            $week = ArraySequence(collection($week)->toArray(), "visit_total");

            // 数组截取
            $week = array_slice($week, 0, 10);
        }




        // ------------------------回帖周榜-------------------------

        // 查询本周
        $date = new \DateTime();

        // 获取本周的第一天  默认为该周的第一天 星期一
        $date->modify('this week');
        $start = strtotime($date->format('Y-m-d'));

        // 获取本周的周日
        $date->modify('this week +6 days');
        $end = strtotime($date->format('Y-m-d'));

        // 查询回帖周榜
        $sql = "SELECT count(*) AS num, user.nickname,user.avatar,user.id FROM pre_comment AS comment LEFT JOIN pre_user AS user ON comment.userid = user.id WHERE comment.createtime between $start and $end GROUP BY comment.userid ORDER BY num DESC LIMIT 12";

        // 查询出来的数据
        $userlist = Db::query($sql);


        // 查询评论------------------------------------------------
        $commentlist = model('Post.Comment')
            ->with(['user'])
            ->where(['postid' => $postid])
            ->order('id', 'asc')
            ->order('level', 'asc')
            ->select();


        if ($commentlist) {
            // 引用变量
            foreach ($commentlist as $item) {
                // 点赞
                $like = explode(' ', $item['like']);
                $userid = isset($LoginUser['id']) ? $LoginUser['id'] : 0;

                //给每条记录都新增一个自定义属性
                //这个字段如果为true 就是点过赞  等于false 就是没点赞
                $item['like_checked'] = in_array($userid, $like) ? true : false;
            }
        }


        $first = array_slice($commentlist, 0, 1);

        // -----------赋值给前台模块----------------
        $this->view->assign([
            'post' => $post,
            'userlist' => $userlist,
            'week' => $week,
            'commentlist' => $commentlist,
            'first' => $first,
            'Collect'=> $Collect
        ]);


        // 加载模板视图
        return $this->view->fetch();
    }

    // 我发表的帖子界面
    public function addpost()
    {
        // 获取当前用户的id
        // 获取cookie
        $LoginUser = cookie('LoginUser') ? cookie('LoginUser') : [];

        // // 查询我的所有帖子 tp内置方法
        $postlist = model('Post.Post')->where(['userid' => $LoginUser['id']])->select();

        // 赋值给前台模板
        $this->view->assign([
            'postlist'=>$postlist,
        ]);
        // 加载模板视图
        return $this->view->fetch();
    }


    // 收藏帖子
    public function collect()
    {
        // 接受ajax传过来的参数
        $postid = $this->request->param('postid', 0);

        // 判断一下这个帖子是否存在
        $post = $this->PostModel->with(['user'])->find($postid);

        if (!$post) {
            $this->error('帖子不存在');
        }

        // 根据这个id查询这个帖子
        $postlist = model('Post.Post')->where(['id' => $postid])->select();
       

        // 获取收藏模型
        $ModelCollect = model('Collect');

        // 组装数据
        $CollectData=[
            'userid'=>$postlist[0]['userid'],
            'postid'=>$postlist[0]['id'],
        ];
       
        
        // 插入
        $RecordStatus = $ModelCollect->save($CollectData);

        if($RecordStatus==FALSE){
            $this->error('收藏失败');
            exit;
        }else{
            $this->success('收藏成功', url('home/index/collect'));
            exit;

        }

        // 加载模板视图
        return $this->view->fetch();
    }

    // 登录
    public function login()
    {
        // 判断是否有post数据
        if ($this->request->isPost()) {
            $vercode = $this->request->param('vercode', '');
            $email = $this->request->param('email', '');
            $password = $this->request->param('password', '');

            // 验证码不正确
            if (!captcha_check($vercode)) {
                $this->error('验证码填写有误，请重新填写');
                exit;
            }

            // 查询用户
            $user = $this->UserModel->where(['email' => $email])->find();

            // 判断用户是否存在
            if (!$user) {
                $this->error('用户不存在');
                exit;
            }

            // 验证密码是否正确
            $salt = $user['salt'];
            // 加密密码
            $password = md5($password . $salt);
            if ($password != $user['password']) {
                $this->error('密码不正确');
                exit;
            }

            // 设置数据要保存到cookie里面的
            $data = [
                'id' => $user['id'],
                'nickname' => $user['nickname'],
                'avatar' => is_file("." . $user['avatar']) ? $user['avatar'] : '',
                'vip' => $user['vip'],
                'auth' => $user['auth']
            ];

            // 保存到cookie中，不设置时间的情况下，默认是关闭浏览器自动消失
            // cookie('保存的cookie名字',要保存的数据,保存的时间)
            cookie('LoginUser', $data);


            // 跳转到用户中心
            $this->success('登录成功', url('home/user/index'));
            exit;
        }
        // 加载模板视图
        return $this->view->fetch();
    }

    // 注册
    public function register()
    {
        // 判断是否有表单提交  $this是当前控制器
        if ($this->request->isPost()) {

            // 获取register页面的表单数据
            // $params = $this->request->param();
            // 获取页面中的某个数据
            // $email = $this->request->params("email","");
            // 获取post方式提交的表单数据
            // $email = $this->request->post("email","");
            // $post = $this->request->post();

            // 获取验证码
            $vercode = $this->request->param('vercode', '');

            // 获取邮箱
            $email = $this->request->param('email', '');

            // 判断有没有通过验证码
            if (!captcha_check($vercode)) {
                $this->error('验证码输入错误');
                exit;
            }



            // 接受提交上来的密码和确认密码
            $password = $this->request->param('password', '');
            $repass = $this->request->param('repass', '');

            if (empty($password)) {
                $this->error('密码不能为空');
                exit;
            }
            if ($password != $repass) {
                $this->error('密码和确认密码不一致');
                exit;
            }


            // 调用common.php里面的公共函数
            // 密码盐
            $salt = randstr(5);
            // 加密后的密码
            $password = md5($password . $salt);

            // 昵称   preg_replace替换 把@后面包括@替换成空
            $nickname = preg_replace('/@.*/', '', $email);

            // 组装数据
            $data = [
                'email' => $email,          //邮箱
                'password' => $password,      //密码
                'salt' => $salt,            //密码盐
                'nickname' => $nickname,    //用户名
                'point' => 0,                 //积分
                'vip' => 0,                   //vip
                'auth' => 0,                  //认证
                'sex' => 0                    //性别
            ];

            // 插入数据成功返回条数 ，失败返回false
            $result = $this->UserModel->validate('common/User/User')->save($data);

            if ($result === FALSE) {
                // getError  返回插入失败的错误信息
                $this->error($this->UserModel->getError());
                exit;
            } else {
                $this->success('注册成功,返回登录界面', url('home/index/login'));
                exit;
            }
        }

        // 加载模板视图
        return $this->view->fetch();
    }

    // 找回密码
    public function retrieve()
    {


        // 加载模板视图
        return $this->view->fetch();
    }

    // 找回密码链接地址页面
    public function retrieves()
    {

        // 判断是否有表单提交
        if ($this->request->isPost()) {
            // 接受表单中的隐藏域关键词
            $action = $this->request->param('action', '');

            // 接受隐藏域的value值
            if ($action == 'retrieve') {

                // 获取验证码
                $vercode = $this->request->param('vercode', '');

                // 判断有没有通过验证码
                if (!captcha_check($vercode)) {
                    $this->error('验证码输入错误');
                    exit;
                }

                // 接受表单提交上来的密码和确认密码
                $email = $this->request->param('email', '', 'trim');
                $password = $this->request->param('password', '', 'trim');  //密码
                $repass = $this->request->param('repass', '', 'trim');      //确认密码

                if (empty($password)) {
                    $this->error('新密码不能为空');
                    exit;
                }

                if (empty($repass)) {
                    $this->error('确认密码不能为空');
                    exit;
                }

                if ($password != $repass) {
                    $this->error('新密码和确认密码不一致');
                    exit;
                }

                // 重新生成一个密码盐
                $salt = randstr(5);

                // 重新加密新的密码
                $password = md5($password . $salt);

                // 用邮箱查询数据库
                $sql = "SELECT user.id FROM pre_user AS user WHERE email='$email'";

                // 获取查询语句里面的值   这里获取的是二维数组
                $userid = Db::query($sql);

                // 二维数组转化为一维
                $userid = array_column($userid, 'id');

                // 获取一维数组里面下标为0的值
                $userid = $userid[0];

                // 整型转化为字符串
                $userid = strval($userid);


                // 组装数据
                $UserData = [
                    'id' => $userid,
                    'salt' => $salt,
                    'password' => $password,
                    'email' => $email
                ];


                // 更新数据 返回影响行数
                $result = $this->UserModel->validate('Common/User/User')->isUpdate(true)->save($UserData);
                // var_dump($result);
                // exit;

                if ($result === FALSE) {
                    $this->error($this->UserModel->getError());
                    exit;
                } else {
                    // 删除cookie
                    cookie('LoginUser', null);
                    $this->success('重设密码成功', url("home/index/login"));
                    exit;
                }
            }
        }
        // 加载模板视图
        return $this->view->fetch();
    }


    // 找回密码的邮件
    public function retr()
    {
        //判断是否是ajax请求
        if ($this->request->isAjax()) {
            //接受ajax传上来的邮箱
            $email = $this->request->param('email', '');

            // 查询用户
            $user = $this->UserModel->where(['email' => $email])->find();

            // 判断用户是否存在
            if (!$user) {
                $this->error('用户不存在');
                exit;
            }

            $content = "<a target='_blank' href='http://www.teach.com/home/index/retrieves/?email=$email'>点击邮件找回密码</a>";

            //调用公共函数库中封装邮件发送
            $result = retr($email, $content);

            if ($result) {
                $this->success('邮件已发送');
                exit;
            } else {
                $this->error('邮件发送失败，请稍后重试');
                exit;
            }
        }
    }


    // 退出
    public function logout()
    {
        // 删除cookie
        cookie('LoginUser', null);

        // 跳转
        $this->success('退出成功', url('home/index/login'));
        exit;
    }


    // 签到
    public function sign()
    {
        // 判断是否为ajax请求
        //判断是否为ajax请求
        if ($this->request->isAjax()) {
            //判断是否有登录
            //获取cookie
            $LoginUser = cookie('LoginUser') ? cookie('LoginUser') : [];

            if (empty($LoginUser)) {
                $this->error('请先登录');
                exit;
            }

            //用户Id
            $userid = isset($LoginUser['id']) ? $LoginUser['id'] : 0;

            //查询数据库
            $LoginUser = $this->UserModel->find($userid);

            //没有找到这个人
            if (!$LoginUser) {
                //清除掉伪造的cookie缓存
                cookie('LoginUser', null);
                $this->error('非法登录');
                exit;
            }

            //查询当天内用户是否有签到记录
            $where = [
                'userid' => $userid,
                'state' => 4
            ];

            $record = model('User.Record')
                ->whereTime('createtime', 'today')
                ->where($where)
                ->find();

            if ($record) {
                $this->error('您已签到，无须重复签到');
                exit;
            }


            //添加消费记录，更新用户表  事务
            $ModelRecord = model('User.Record');
            $ModelUser = model('User.User');

            //开启事务
            $ModelUser->startTrans();
            $ModelRecord->startTrans();

            //查询系统的签到积分数
            $SignPoint = model('Config')->where(['key' => 'SignPoint'])->value('value');
            $SignPoint = abs(intval($SignPoint)) > 0 ? abs(intval($SignPoint)) : 5;

            //组装数据
            $now = date("Y-m-d H:i", time());

            $RecordData = [
                'point' => $SignPoint,
                'content' => "【签到】$now 签到 获得 $SignPoint 积分",
                'state' => 4,
                'userid' => $userid
            ];

            //插入到消费记录表
            $RecordStatus = $ModelRecord->validate('common/User/Record')->save($RecordData);

            if ($RecordStatus === FALSE) {
                $this->error($this->ModelRecord->getError());
                exit;
            }

            //用户积分
            $UserPoint = $LoginUser['point'];

            //更新用户积分
            $UpdatePoint = bcadd($UserPoint, $SignPoint);

            //更新数据
            $UserData = [
                'id' => $userid,
                'point' => $UpdatePoint
            ];

            //更新用户积分
            $UserStatus = $ModelUser->isUpdate(true)->save($UserData);

            if ($UserStatus === FALSE) {
                //回滚
                $ModelRecord->rollback();
                $this->error($ModelUser->getError());
                exit;
            }

            //两个动作都要同时成功才提交事务
            if ($RecordStatus === FALSE || $UserStatus === FALSE) {
                $ModelUser->rollback();
                $ModelRecord->rollback();
                $this->error('签到失败');
                exit;
            } else {
                //提交事务
                $ModelRecord->commit();
                $ModelUser->commit();
                $this->success("签到成功 获得{$SignPoint}积分");
                exit;
            }
        }
    }

    // 生成验证码的方法
    public function vercode()
    {
        // 配置选择
        $config = [
            // 使用中文字
            // 'useZh'=>true,
            // 设置长度
            'length' => 3
        ];
        // 生成验证码
        $captcha = new Captcha($config);

        return $captcha->entry();
    }

    //邮箱验证方法
    public function email()
    {
        $auth = $this->request->param('auth', '', 'trim');

        //查询所有的用户
        $userlist = $this->UserModel->column('id,email,salt,auth');

        //找到验证用户id
        $userid = 0;
        $auth = 0;

        foreach ($userlist as $item) {
            $salt = $item['salt'];
            $email = $item['email'];

            //加密
            $rand = md5($email . $salt);

            //说明就找到人了
            if ($auth == $rand) {
                $userid = $item['id'];
                $auth = $item['auth'];
            }
        }

        if (!$userid) {
            $this->error('用户不存在');
            exit;
        }

        if ($auth) {
            $this->error('已通过邮箱认证，无须重复认证');
            exit;
        }

        //组装数据
        $UserData = [
            'id' => $userid,
            'auth' => 1
        ];

        //更新用户的认证状态
        $result = $this->UserModel->isUpdate(true)->save($UserData);

        if ($result === FALSE) {
            $this->error('认证失败,请稍后重试', url('home/user/profile'));
            exit;
        }

        //先去获取cookie 
        if (cookie('LoginUser')) {
            //查询最新的这个人的数据
            $user = $this->UserModel->find($userid);

            //要保存到cookie当中的
            $data = [
                'id' => $user['id'],
                'nickname' => $user['nickname'],
                'avatar' => is_file("." . $user['avatar']) ? $user['avatar'] : '',
                'vip' => $user['vip'],
                'auth' => $user['auth'],
            ];

            //设置到cookie中 不设置时间的情况 默认是关闭浏览器自动消失
            cookie('LoginUser', $data);
        }

        $this->success('认证成功', url('home/user/profile'));
        exit;
    }


}
